﻿using UnityEngine;
using LuaInterface;
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine.UI;
using System.Threading;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using DG.Tweening;

namespace YanhuaMMO {    
    public class LuaBehaviour : View {
        private string data = null;
        private Dictionary<GameObject, LuaFunction> buttons = new Dictionary<GameObject, LuaFunction>();
        private Dictionary<GameObject, object> buttonsArgs = new Dictionary<GameObject, object>();

        private Dictionary<string, LuaFunction> sliders = new Dictionary<string, LuaFunction>();
        private Dictionary<string, LuaFunction> dropDowns = new Dictionary<string, LuaFunction>();

        // WG 现有的回调函数不支持对象调用所以采用以下方法做兼容
        // 在Lua中赋值
        public LuaTable luaFuncTable;
        public LuaFunction luaAwakeFunc;
        public LuaFunction luaStartFunc;
        public LuaFunction luaOnDisableFunc;
        public LuaFunction luaOnEnableFunc;
        public LuaFunction luaOnDestroyFunc;

        protected void Awake() {

            if (luaAwakeFunc != null)
                luaAwakeFunc.Call(luaFuncTable);
            else
                Util.CallDisposeMethod(name, "Awake", gameObject);
       
        }

        protected void Start() {
            if (luaStartFunc != null)
                luaStartFunc.Call(luaFuncTable);
            else
                Util.CallDisposeMethod(name, "Start");
        }

        protected void OnDisable() {
            if (luaOnDisableFunc != null)
                luaOnDisableFunc.Call(luaFuncTable);
            else
                Util.CallDisposeMethod(name, "OnDisable");
        }
        protected void OnEnable()
        {
            LuaManager luaMgr = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua);

            LuaTable luaTable = luaMgr.GetTable(name);
            LuaTable metaTable = null;
            LuaFunction enabelFunc = null;
            if (luaTable != null)
                metaTable = luaTable.GetMetaTable();
                if (metaTable != null)
                    enabelFunc = metaTable.GetLuaFunction("Enable");
            if (enabelFunc != null || luaOnEnableFunc != null)
                if(enabelFunc != null) enabelFunc.Call(luaFuncTable);
                else luaOnEnableFunc.Call(luaFuncTable);
            else
                Util.CallDisposeMethod(name, "OnEnable");

            if (enabelFunc != null) enabelFunc.Dispose();
            if (metaTable != null) metaTable.Dispose();
            if (luaTable != null) luaTable.Dispose();
        }

        protected void OnClick() {
            Util.CallDisposeMethod(name, "OnClick");
        }

        protected void OnClickEvent(GameObject go) {
            Util.CallDisposeMethod(name, "OnClick", go);
        }


        private void Update()
        {
            
        }

        

        /// <summary>
        /// 添加单击事件
        /// </summary>
        public void AddClick(GameObject go, LuaFunction luafunc,object args = null , LuaTable luafuncTable = null) {
            if (go == null || luafunc == null) return;
            //if (buttons.ContainsKey(go.name)) return;
            if (buttons.ContainsKey(go))
            {
                RemoveClick(go);
            }
            if (buttonsArgs.ContainsKey(go))
            {
                buttonsArgs.Remove(go);
            }
            //添加
            buttons.Add(go, luafunc);
            buttonsArgs.Add(go, args);
            go.GetComponent<Button>().onClick.AddListener(
                delegate() {
                    if (luafuncTable == null)
                        luafunc.Call(go, buttonsArgs[go]);
                    else
                        luafunc.Call(luafuncTable, go, buttonsArgs[go]);
                }
            );
        }

        /// <summary>
        /// 添加长按事件
        /// </summary>
        public void AddLongClick(GameObject go, LuaFunction luafunc, object args = null, LuaTable luafuncTable = null)
        {
            if (go == null || luafunc == null) return;
           
            go.GetComponent<LongClickButton>().onLongPress.AddListener(
                delegate () {
                    if (luafuncTable == null)
                        luafunc.Call(go);
                    else
                        luafunc.Call(luafuncTable,go);
                }
            );
        }
      
        /// <summary>
        /// 添加滑动条valueChange事件
        /// </summary>
        public void AddSliderChange(GameObject go, LuaFunction luafunc, LuaTable luafuncTable = null)
        {
            if (go == null || luafunc == null) return;
            if (sliders.ContainsKey(go.name))
            {
                RemoveSlider(go);
            }
            sliders.Add(go.name, luafunc);
            go.GetComponent<Slider>().onValueChanged.AddListener(
                delegate (float value) {
                    if (luafuncTable == null)
                        luafunc.Call(value);
                    else
                        luafunc.Call(luafuncTable);
                }
            );
            
        }

        /// <summary>
        /// 删除slider change事件
        /// </summary>
        /// <param name="go"></param>
        public void RemoveSlider(GameObject go)
        {
            if (go == null) return;
            LuaFunction luafunc = null;
            if (sliders.TryGetValue(go.name, out luafunc))
            {
                luafunc.Dispose();
                luafunc = null;
                sliders.Remove(go.name);
            }
        }

        /// <summary>
        /// 添加DropdownvalueChange事件
        /// </summary>
        public void AddDropdownChange(GameObject go, LuaFunction luafunc, LuaTable luafuncTable = null)
        {
            if (go == null || luafunc == null) return;
            if (dropDowns.ContainsKey(go.name))
            {
                RemoveDropdown(go);
            }
            dropDowns.Add(go.name, luafunc);
            go.GetComponent<Dropdown>().onValueChanged.AddListener(
                delegate (int value)
                {
                    if (luafuncTable == null)
                        luafunc.Call(value);
                    else
                        luafunc.Call(luafuncTable,value);
                }
            );
        }

        /// <summary>
        /// 删除Dropdownchange事件
        /// </summary>
        /// <param name="go"></param>
        public void RemoveDropdown(GameObject go)
        {
            if (go == null) return;
            LuaFunction luafunc = null;
            if (dropDowns.TryGetValue(go.name, out luafunc))
            {
                luafunc.Dispose();
                luafunc = null;
                dropDowns.Remove(go.name);
            }
        }

        /// <summary>
        /// 删除单击事件
        /// </summary>
        /// <param name="go"></param>
        public void RemoveClick(GameObject go) {
            if (go == null) return;
            LuaFunction luafunc = null;
            if (buttons.ContainsKey(go)) {
                if (buttons.TryGetValue(go, out luafunc))
                {
                    luafunc.Dispose();
                    luafunc = null;
                    buttons.Remove(go);
                    go.GetComponent<Button>().onClick.RemoveAllListeners();
                }
            }
        }

        /// <summary>
        /// 删除长按事件
        /// </summary>
        /// <param name="go"></param>
        public void RemoveLongClick(GameObject go)
        {
            if (go == null) return;
            go.GetComponent<LongClickButton>().onLongPress.RemoveAllListeners();
        }

        /// <summary>
        /// 清除单击事件
        /// </summary>
        public void ClearClick() {
            foreach (var de in buttons) {
                if (de.Value != null) {
                    de.Value.Dispose();
                }
            }
            buttons.Clear();
            foreach (var de in sliders)
            {
                if (de.Value != null)
                {
                    de.Value.Dispose();
                }
            }
            sliders.Clear();

            foreach (var de in dropDowns)
            {
                if (de.Value != null)
                {
                    de.Value.Dispose();
                }
            }
            dropDowns.Clear();

            
        }

        public void DeleteLuaFunc() 
        {
            if (luaAwakeFunc != null) 
            {
                luaAwakeFunc.Dispose();
                luaAwakeFunc = null;
            }
            if (luaStartFunc != null)
            {
                luaStartFunc.Dispose();
                luaStartFunc = null;
            }
            if (luaOnDisableFunc != null)
            {
                luaOnDisableFunc.Dispose();
                luaOnDisableFunc = null;
            }
            if (luaOnEnableFunc != null)
            {
                luaOnEnableFunc.Dispose();
                luaOnEnableFunc = null;
            }
            if (luaOnDestroyFunc != null)
            {
                luaOnDestroyFunc.Dispose();
                luaOnDestroyFunc = null;
            }
            luaFuncTable = null;
        }

        //-----------------------------------------------------------------
        protected void OnDestroy() {
            ClearClick();
            if (luaOnDestroyFunc != null)
                luaOnDestroyFunc.Call(luaFuncTable);
            else
                Util.CallDisposeMethod(name, "OnDestroy");
            DeleteLuaFunc();

            // 清理lua绑定 不能提前清理 OnDestroy里面还会引用
            LuaManager luaMgr = AppFacade.Instance.GetManager<LuaManager>(ManagerName.Lua);
            if (luaMgr != null)
            {
                LuaTable luaTable = luaMgr.GetTable(name);
                if (luaTable != null) 
                {
                    Util.CallDisposeMethod(name, "OnDestroyAfter", luaTable);
                    luaTable.Dispose();
                }
            }
            

#if ASYNC_MODE
            string abName = name.ToLower().Replace("panel", "");
           // ResManager.UnloadAssetBundle(abName + AppConst.ExtName);
#endif
           // Util.ClearMemory();
            //Debug.LogWarning("~" + name + " was destroy!");
        }
    }
}